package com.wgt.controller;

import com.wgt.domain.Authority;
import com.wgt.domain.User;
import com.wgt.service.authority.AuthorityService;
import com.wgt.service.user.UserService;
import com.wgt.util.ConstraintViolationExceptionHandler;
import com.wgt.vo.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.validation.ConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户控制器.
 * 
 * @author <a href="https://waylau.com">Way Lau</a>
 * @date 2017年2月26日
 */
@Slf4j
@RestController
@RequestMapping("/users")
public class UserController {

	@Autowired
	private UserService userService;

	@Autowired
	private AuthorityService authorityService;


	/**
	 * 查询所用用户
	 * @return
	 */
	@GetMapping
	public ModelAndView list(@RequestParam(value="async",required=false) boolean async,
							 @RequestParam(value="pageIndex",required = false,defaultValue = "0")int pageIndex,
							 @RequestParam(value = "pageSize",required = false,defaultValue = "10")int pageSize,
							 @RequestParam(value = "name",required = false,defaultValue = "")String name,
							 Model model) {
		log.info("####查询所有用户####");
		log.info("param >>> name:[{}],pageIndex:[{}],pageSize:[{}]",name,pageIndex,pageSize);

		Page<User> page = userService.listUserByName(name,pageIndex,pageSize);
		List<User> users = page.getContent();

		model.addAttribute("page",page);
		model.addAttribute("userList",users);

		String viewTemplate = null;
		if(async){
			viewTemplate = "users/list :: #mainContainerRepleace";
			log.info("request is a async,viewTemplate >>>[{}]",viewTemplate);
		}else {
			viewTemplate = "users/list";
			log.info("request is a forward,viewTemplate >>>[{}]",viewTemplate);
		}
		return new ModelAndView(viewTemplate,"userModel",model);
	}

	/**
	 * 初始化添加用户
	 * @param model
	 * @return
	 */
	@GetMapping("/add")
	public ModelAndView initAdd(Model model){
		log.info("####初始化新增用户####");
		model.addAttribute("user", new User());
		return new ModelAndView("users/add", "userModel", model);
	}

	/**
	 * 创建用户
	 * @param user
	 * @param authorityId
	 * @return
	 */
	@PostMapping
	public ResponseEntity createUser(User user,Integer authorityId){
		log.info("####新增用户####");
		log.info("get authorities by id >>>>[{}]",authorityId);

		List<Authority> authorities = new ArrayList<>();
		authorities.add(authorityService.getAuthorityById(authorityId));

		log.info("user authorities >>>>[{}]",authorities);

		user.setAuthorities(authorities);

		log.info("user bean content >>>>[{}]",user);
		if(user.getId() == null) {
			user.setEncodePassword(user.getPassword()); // 加密密码
		}else {
			// 判断密码是否做了变更
			User originalUser = userService.getUserById(user.getId());
			String rawPassword = originalUser.getPassword();
			PasswordEncoder encoder = new BCryptPasswordEncoder();
			String encodePasswd = encoder.encode(user.getPassword());
			boolean isMatch = encoder.matches(rawPassword, encodePasswd);
			if (!isMatch) {
				user.setEncodePassword(user.getPassword());
			}else {
				user.setPassword(user.getPassword());
			}
		}
		log.info("user password encode >>>>[{}]",user.getPassword());
		try {
			userService.saveOrUpdateUser(user);
			log.info(">>>>save user to databases success");
		}  catch (ConstraintViolationException e)  {

			log.info(">>>>save user to databases failure");
			return ResponseEntity.ok().body(new Response(false, ConstraintViolationExceptionHandler.getMessage(e)));
		}
		return ResponseEntity.ok().body(new Response(true, "处理成功", user));
	}

	@GetMapping("/edit/{id}")
	public ModelAndView initEdit(@PathVariable("id")Integer id,Model model){
		log.info("####初始化编辑用户####");
		log.info("get user by id >>>>[{}]",id);
		User user = userService.getUserById(id);

		log.info("user bean content >>>>[{}]",user);
		log.info("user authorities ROLE_USER >>>[{}]",user.getAuthorities());
		model.addAttribute("user", user);
		return new ModelAndView("users/edit", "userModel", model);
	}

	/**
	 * 删除用户
	 * @param id
	 * @return
	 */
	@DeleteMapping(value = "/{id}")
	public ResponseEntity<Response> delete(@PathVariable("id") Integer id, Model model) {
		try {
			userService.removeUser(id);
		} catch (Exception e) {
			return  ResponseEntity.ok().body( new Response(false, e.getMessage()));
		}
		return  ResponseEntity.ok().body( new Response(true, "处理成功"));
	}

	/////////以下为异步验证方法

	/**
	 *验证邮箱
	 * @param email
	 * @return
	 */
	@GetMapping("/validEmail")
	public ResponseEntity validEmail(@RequestParam("email")String email,@RequestParam(value = "username",required = false)String username){
		log.info("####异步查询邮箱####");
		if(StringUtils.isBlank(email)){
			return ResponseEntity.ok().body(new Response(false, "邮箱不能为空"));
		}
		log.info("param email >>>>> [{}]",email);
		User user = userService.findByEmail(email);

		if(user != null) {
			log.info("user bean content >>>>> [{}]",user);
			if(username != null){
				log.info("param username >>>>> [{}]",username);
				if(!username.equals(user.getUsername())){
					return ResponseEntity.ok().body(new Response(false,"邮箱已经注册"));
				}
			}else {
				return ResponseEntity.ok().body(new Response(false, "邮箱已经注册"));
			}
		}
		return ResponseEntity.ok().body(new Response(true, "000"));
	}

	/**
	 * 验证用户名
	 * @param username
	 * @return
	 */
	@GetMapping("/validUsername")
	public ResponseEntity validUsername(@RequestParam("username")String username){
		log.info("####异步查询用户名####");
		if(StringUtils.isBlank(username)){
			return ResponseEntity.ok().body(new Response(false, "用户名不能为空"));
		}
		User user = userService.findByUsername(username);
		if (user != null){
			return ResponseEntity.ok().body(new Response(false, "用户名已经存在"));
		}
		return ResponseEntity.ok().body(new Response(true, "000"));
	}
}
